/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
 
#ifndef HTTP_SEMAPHORE
#define HTTP_SEMAPHORE

#include "base.h"
#include "server.h"
#include <pthread.h>
#include <semaphore.h>

/* ----------------------------- pool_th ------------------------------ */

/*	Estrutura de Threads Identificadas
	possui um pthread_t que é a thread propriamente dita
	e um identificador (ID)	*/
#ifndef THREAD_T
#define THREAD_T
typedef struct {
	pthread_t thread;
	int id;
} thread_t;
#endif

sem_t semaphore;	// estrutura responsável por exclusão mútua (semáforo)
int lg_listen_started;		// flag que indica se o listen já foi iniciado

/*	pool_th: Estrutura que implementa um pool de threads
	E funções relacionadas.	*/
typedef struct {
	
	int nthreads;				// número e threads
	int *threads;			// ponteiro para um array de threads
	
} pool_th;

typedef struct {

	int nthreads;				// número e threads
	thread_t *threads;			// ponteiro para um array de threads

} pool_th_old;

/*	estrutura para passar de parâmetro
	à função execute	*/
typedef struct {
	int sockfd;					// socket fd do servidor
	int new_fd;					// socket fd para usar no accept
	struct sockaddr_in client;	// estrutura para guardar informações do client
	socklen_t client_len;		// tamanho da estrutura
	int id;						// id da thread
} exec_params;

/*	função a ser executada pelas threads
	chama o accept	*/
void execute_accept(exec_params params);
/*	função a ser executada pelas threads.
	Esta função é sincronizada pelo semáforo
	Parâmetros
		- void* p: parâmetros (struct: exec_params)	*/
void* execute(void* param);

/*	Instancia um pool de threads com n posições,
	inicializa o semáforo do mesmo e o retorna
	Parâmetros:
		- int n:			número de threads no pool
		- int lg_start_sem: booleano (1: utiliza o semáforo; 0: não utiliza o semáforo)	*/
pool_th pool_init(int n);

/*	Chama a execução das threads do pool
	cada thread executará a função 'execute'
	Parâmetros:
		- pool_th pool: pool de threads que serão iniciadas
		- int sockfd:		socket do servidor (listening socket)	*/
void pool_start(pool_th pool, int sockfd);

/*	Cancela a execução de todas as threads
	e libera o espaço alocado para as mesmas	*/
void pool_destroy(pool_th p);

/*	Função utilizada para testes	*/
void sem_simulate(char* port, int nthreads);
void sem_testing(int id);

#endif
